#ifndef _BUOLA_WIDGETS_CWIDGET_H_
#define _BUOLA_WIDGETS_CWIDGET_H_

#include <buola/gui/cwindow.h>

#include <buola/utility/uevent.h>
#include <buola/utility/uany.h>

namespace buola { namespace gui {

///\addtogroup widgets
///@{

////////////////////////////////////////////////////////////////////////////

/// widget base class

///
///
///
////////////////////////////////////////////////////////////////////////////

class CWidget : public CWindow
{
public:
    //! style bits (can be extended in derived classes, starting at 1<<8)
    enum
    {
        STYLE_NONE=0,
        STYLE_NOBORDER=             (1<<0), //!< don't draw a border
        STYLE_DISABLED=             (1<<1), //!< window is disabled (no input, display differently)
        STYLE_READONLY=             (1<<2), //!< window is readonly (no input)
        STYLE_FAKE=                 (1<<3), //!< it is a fake window
        STYLE_SMALLFONT=            (1<<4), //!< use a smaller font
        STYLE_PLAIN=                (1<<5), //!< use simple version of widget
        STYLE_EDITOR=               (1<<6), //!< is an editor
        STYLE_INBAR=                (1<<7), //!< version of widget to use in a bar
        STYLE_GENERAL=              (0xff), //!< bits defined in CWindow
        STYLE_SPECIFIC=             ~STYLE_GENERAL  //!< bits not defined in CWindow
    };

    typedef uint64_t TStyle;


public:
    CWidget();
    ~CWidget();

//! \name widget properties
//! Some widgets allow changing some of their properties by name, using
//! these functions.
//@{
    //! get a list of all properties in the widget
    virtual void GetPropertyNames(std::vector<std::string> &pNames);

    //! sets a property
    virtual void SetProperty(const std::string &pName,const UAny&);
    //! gets a property
    virtual void GetProperty(const std::string &pName,UAny &pValue);

    //! process a property which directly changes a style bit
    bool ProcessStyleProperty(const std::string &p,const UAny &v,
                              const std::string &s,TStyle b);
//@}

    //! sets a style bit
    void SetStyleBit(TStyle pStyle)
    {
        SetStyle(mStyle|pStyle);
    }

    //! unsets a style bit
    void UnsetStyleBit(TStyle pStyle)
    {
        SetStyle(mStyle&(~pStyle));
    }

    //! sets the style
    void SetStyle(TStyle pStyle)
    {
        if(mStyle==pStyle) return;
        TStyle lOld=mStyle;
        mStyle=pStyle;
///\todo something similar        if(GetFlag(FLAG_CREATED))
            OnStyleChanged(lOld);
    }

    //! sets some bits of the style
    void SetStyle(TStyle pMask,TStyle pStyle)
    {
        SetStyle((mStyle&(~pMask))|(pStyle&pMask));
    }

    //! gets the style
    TStyle GetStyle()                           {   return mStyle;      }
    //! checks the style
    TStyle GetStyle(TStyle pStyle)  {   return (mStyle&pStyle)==pStyle; }

    virtual void OnStyleChanged(TStyle) {}

private:
    TStyle mStyle;
};

///@}

/*namespace gui*/ } /*namespace buola*/ }

#endif
